﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using CustomCharacter;
using CustomCharacter.Ability;
using CustomCharacter.Interfaces;
using CustomCharacter.VoiceChat;
using CustomPlayerEffects;
using Exiled.API.Extensions;
using Exiled.API.Features;
using Exiled.Events.EventArgs.Interfaces;
using Exiled.Events.EventArgs.Item;
using Exiled.Events.EventArgs.Player;
using Exiled.Events.EventArgs.Scp914;
using InventorySystem.Items.Jailbird;
using JetBrains.Annotations;
using MEC;
using PlayerRoles;
using PlayerStatsSystem;
using RgCore.API;
using RgCore.PlayerHud;
using RgCore.Misc;
using RgCore.Events;
using UnityEngine;

namespace Scp2686
{
    [RoleInfo("SCP-2686-2", "Scp2686", RoleTypeId.None, RoleTypeId.Tutorial, MaxHealth = 100)]
    public sealed class Scp26862(int id) : CustomCharacter.CustomCharacter(id), IScpNumber, ISubProject
    {
        [CanBeNull]
        public static Player Scp2686Player =>
            AllCharacters.FirstOrDefault(p => p is Scp2686)?.Player;

        [Description("能量")]
        public string EnergyStr
        {
            get
            {
                AbilityInfo ab = Player.GetAbility("Scp26862_Attribute_1");
                return ab.Ability == null ? "null" : $"{ab.Datas["energy"]}/{ab.Datas["MAX_ENERGY"]}";
            }
        }

        public override Color32 RoleColor { get; } = new Color32(196, 76, 29, 255);

        public string ScpNumber => "2686-2";

        public Type ParentProject => typeof(Scp2686);

        public override IEnumerable<Ability> AbilityRegister()
        {
            return
            [
                new Ability("Scp26862_Offensive_2", "消耗不等量能量值，立即传送到同区域的SCP-2686身边", AbilityType.Offensive, 30u,
                    Scp2686_2_Offensive_2_Function, Scp2686_2_Offensive_2_Checker, null, null, GetType()),
                new Ability("Scp26862_Offensive_3", "消耗100能量值，立即获得100AHP和30%移速加成（持续15秒）", AbilityType.Offensive, 30u,
                    Scp2686_2_Offensive_3_Function, Scp2686_2_Offensive_3_Checker, null, null, GetType()),
                new AttributeAbility("Scp26862_Attribute_1", "特性,一大堆东西", Scp2686_2_Attribute_1, true,
                    [
                        EventProcessor.OnHurting,
                        Exiled.Events.Handlers.Player.Died,
                        Exiled.Events.Handlers.Player.SearchingPickup,
                        Exiled.Events.Handlers.Item.ChargingJailbird,
                        Exiled.Events.Handlers.Player.DroppingItem,
                        Exiled.Events.Handlers.Scp914.UpgradingInventoryItem,
                        EventProcessor.OnDying,
                    ],
                    [
                        new KeyValuePair<string, object>("energy", 0),
                        new KeyValuePair<string, object>("MAX_ENERGY", 200)
                    ], GetType())
            ];
        }

        private static bool Scp2686_2_Offensive_3_Checker(Player player, out string response)
        {
            AbilityInfo ab = player.GetAbility("Scp26862_Attribute_1");
            if (ab.Ability == null)
            {
                response = "此技能需要SCP-2686-2的特性技能才能正常使用";
                return false;
            }

            if ((int)ab.Datas["energy"] < 100)
            {
                response = "此技能释放需要100能量";
                return false;
            }

            response = "";
            return true;
        }

        private static bool Scp2686_2_Offensive_2_Checker(Player player, out string response)
        {
            if (Scp2686Player == null)
            {
                response = "SCP-2686已不存在";
                return false;
            }

            if (Scp2686Player.Zone != player.Zone)
            {
                response = "你与SCP-2686不在同一区域";
                return false;
            }

            AbilityInfo ab = player.GetAbility("Scp26862_Attribute_1");
            if (ab.Ability == null)
            {
                response = "此技能需要SCP-2686-2的特性技能才能正常使用";
                return false;
            }

            response = "";
            return true;
        }

        private static AbilityOutput Scp2686_2_Offensive_3_Function(Player player, ref AbilityInfo info, IExiledEvent e,
            AbilityTrigger trigger)
        {
            switch (trigger)
            {
                case AbilityTrigger.Active:
                {
                    if (info.CooldownStatus.Status is CooldownStatus<Player>.CdStatus.Activating
                        or CooldownStatus<Player>.CdStatus.LongActivating)
                    {
                        return false;
                    }

                    AbilityInfo ab = player.GetAbility("Scp26862_Attribute_1");
                    ab.Datas["energy"] = (int)ab.Datas["energy"] - 100;
                    player.AddAhp(100f, 100f, 10f, 1f, 15f);
                    player.EnableEffect<MovementBoost>(100, 15f);
                    info.CooldownStatus.StartCD();
                    return new AbilityOutput(true, true, 15, "强化！获得100全抗AHP和200%移速");
                }
                case AbilityTrigger.Deactive:
                {
                    return true;
                }
            }

            return true;
        }

        private static AbilityOutput Scp2686_2_Offensive_2_Function(Player player, ref AbilityInfo info, IExiledEvent e,
            AbilityTrigger trigger)
        {
            if (trigger != AbilityTrigger.Active)
                return false;
            float distance = Vector3.Distance(player.Position, Scp2686Player.Position);
            AbilityInfo ab = player.GetAbility("Scp26862_Attribute_1");
            int cost = Math.Min((int)distance, 100);
            int energy = (int)ab.Datas["energy"];
            if (cost > energy)
            {
                return new AbilityOutput(false, "你的能量不足以发动传送");
            }

            ab.Datas["energy"] = energy - cost;
            player.Teleport(Scp2686Player.Position);
            return true;
        }

        private static AbilityOutput Scp2686_2_Attribute_1(Player player, ref AbilityInfo info, IExiledEvent e,
            AbilityTrigger trigger)
        {
            int energy = (int)info.Datas["energy"];
            if (e is null && trigger == AbilityTrigger.Update)
            {
                energy = Math.Min(energy + 1, (int)info.Datas["MAX_ENERGY"]);
                info.Datas["energy"] = energy;
                return new AbilityOutput(true);
            }

            if (e is DiedEventArgs diedEventArgs && diedEventArgs.Attacker == player)
            {
                Scp2686Player.AddScore(10, "SCP-2686-2队员击杀");
                return new AbilityOutput(true);
            }

            if (e is DyingEventArgs dying && dying.Player == player)
            {
                player.RemoveItem(x => x.Type == ItemType.Jailbird);
            }

            if (e is HurtingEventArgs { IsAllowed: true } ev && ev.DamageHandler.Base is AttackerDamageHandler)
            {
                if (ev.Player == player)
                {
                    var attack_cc = ev.Attacker.GetCharacterInstance();
                    if (attack_cc is Scp2686 or Scp26862)
                    {
                        ev.Amount = 0f;
                        ev.IsAllowed = false;
                        return true;
                    }
                }
                else if (ev.Attacker == player)
                {
                    if (ev.DamageHandler.Base is JailbirdDamageHandler jailbird &&
                        player.CurrentItem is { Base: JailbirdItem j })
                    {
                        j._hitreg.TotalMeleeDamageDealt = 0f;
                        if (ev.Amount >= 100f)
                        {
                            ev.Amount = 0f;
                            ev.IsAllowed = false;
                            return true;
                        }
                        else
                        {
                            ev.Amount *= 0.5f;
                        }
                    }

                    var cc = ev.Player.GetCharacterInstance();
                    if (cc is Scp2686 or Scp26862)
                    {
                        ev.Amount = 0f;
                        ev.IsAllowed = false;
                        return true;
                    }
                }

                energy = Math.Min(energy + (int)Math.Floor(ev.Amount / 2f), (int)info.Datas["MAX_ENERGY"]);
                info.Datas["energy"] = energy;
                return true;
            }

            if (e is DroppingItemEventArgs { IsAllowed: true } drop && drop.Player == player &&
                drop.Item.Type == ItemType.Jailbird)
            {
                drop.IsAllowed = false;
                return true;
            }

            if (e is SearchingPickupEventArgs { IsAllowed: true } searchingPickupEventArgs)
            {
                ItemCategory itemCategory = searchingPickupEventArgs.Pickup.Type.GetCategory();
                if (searchingPickupEventArgs.Player == player && (itemCategory != ItemCategory.Medical &&
                                                                  itemCategory != ItemCategory.Keycard &&
                                                                  searchingPickupEventArgs.Pickup.Type !=
                                                                  ItemType.SCP500 &&
                                                                  CustomItem.CustomItem.GetItem(searchingPickupEventArgs
                                                                      .Pickup.Serial) is not MiniMicroHID.MiniMicroHID))
                {
                    searchingPickupEventArgs.IsAllowed = false;
                    player.DeleteMsg("scp2686_hint", update: false);
                    player.SendRawMsg("scp2686_hint", "<color=red>你只能拾起 钥匙卡 和 医疗物品!</color>", 3u,
                        ScreenLocation.CenterTop, update: true);
                }
            }

            if (e is UpgradingInventoryItemEventArgs { Item.Type: ItemType.Jailbird } upgradingItemEventArgs &&
                upgradingItemEventArgs.Player == player)
            {
                upgradingItemEventArgs.IsAllowed = false;
                return new AbilityOutput(true);
            }

            if (e is ChargingJailbirdEventArgs jailbirdEventArgs && jailbirdEventArgs.Player == player)
            {
                ((JailbirdItem)jailbirdEventArgs.Item.Base).TotalChargesPerformed = 0;
                return new AbilityOutput(true);
            }

            return new AbilityOutput(true);
        }

        public override void Role_Activate()
        {
            base.Role_Activate();
            Player.Scale = Vector3.one * 1.1f;
            Player.AddItem(ItemType.Medkit);
            Player.AddItem(ItemType.Adrenaline);
            Player.AddItem(ItemType.Jailbird);
            Player.VC_AddSender("Scp2686");
            Player.VC_AddListener("Scp2686");
        }

        public override void Role_Deactive()
        {
            base.Role_Deactive();
            Timing.CallDelayed(0.5f, () => { Player.Scale = Vector3.one; });
            Player.VC_RemoveSender("Scp2686");
            Player.VC_RemoveListener("Scp2686");
        }
    }
}